﻿using Furion.DatabaseAccessor;
using Furion.DatabaseAccessor.Extensions;
using Furion.DependencyInjection;
using Furion.DynamicApiController;
using Furion.FriendlyException;
using LimaLims.Application.Service.Sys.Dto;
using LimaLims.Core;
using LimaLims.Core.Entity.System;
using log4net.Core;
using Mapster;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using StackExchange.Redis;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace LimaLims.Application.Service.Sys
{
    /// <summary>
    /// 字典管理
    /// </summary>
    [Route("api")]
    public class SysDictDataService : ISysDictDataService, IDynamicApiController, ITransient
    {
        private readonly IRepository<SysDictData> _sysDictDataRep;  // 字典类型表仓储
        public SysDictDataService(IRepository<SysDictData> sysDictDataRep)
        {
            _sysDictDataRep = sysDictDataRep;
        }
        /// <summary>
        /// 增加
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        [HttpPost("sysDictData/add")]
        public async Task AddDictData(AddDictDataInput input)
        {
            var isExist = await _sysDictDataRep.AnyAsync(u => (u.Code == input.Code || u.Value == input.Value) && u.DictTypeId == input.DictTypeId, false);
            if (isExist) throw Oops.Oh("字典值已存在,名称或编码重复");
            var dictData = input.Adapt<SysDictData>();
            await _sysDictDataRep.InsertAsync(dictData);
        }
        [HttpPost("sysDictData/deleteByDictTypeId")]
        [UnitOfWork]
        public async Task DeleteByTypeId(long dictTypeId)
        {
            var dictDatas = await _sysDictDataRep.Where(u => u.DictTypeId == dictTypeId).ToListAsync();
            await _sysDictDataRep.DeleteAsync(dictDatas);
        }
        /// <summary>
        /// 删除字典值
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        [HttpPost("sysDictData/delete")]
        [UnitOfWork]
        public async Task DeleteDictData(long id)
        {
            var dictData = await _sysDictDataRep.FirstOrDefaultAsync(u => u.Id == id);
            if (dictData == null) throw Oops.Oh("字典值不存在");
            await dictData.DeleteAsync();
        }
        /// <summary>
        /// 字典值详情
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        [HttpGet("sysDictData/detail")]
        public async Task<SysDictData> GetDictData(long id)
        {
            return await _sysDictDataRep.FirstOrDefaultAsync(u => u.Id == id, false);
        }
        /// <summary>
        /// 字典值详情
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        [NonAction]
        public async Task<List<SysDictData>> GetDictDataListByDictTypeId(long dictTypeId)
        {
            return await _sysDictDataRep.DetachedEntities.Where(u => u.DictType.Id == dictTypeId)
                                                         .OrderBy(u => u.Sort)
                                                         .ToListAsync();
        }
        /// <summary>
        /// 分页查询字典值
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        [HttpGet("sysDictData/page")]
        public async Task<PageResult<DictDataOutput>> QueryDictDataPageList([FromQuery] DictDataPageInput input)
        {
            var code = !string.IsNullOrEmpty(input.Code?.Trim());
            var value = !string.IsNullOrEmpty(input.Value?.Trim());
            var dictDatas = await _sysDictDataRep.DetachedEntities
                                  .Where(u => u.DictTypeId == input.DictTypeId)
                                  .Where((code, u => EF.Functions.Like(u.Code, $"%{input.Code.Trim()}%")),
                                         (value, u => EF.Functions.Like(u.Value, $"%{input.Value.Trim()}%")))
                                  .OrderBy(u => u.Sort)
                                  .ProjectToType<DictDataOutput>()
                                  .ToADPagedListAsync(input.PageNo, input.PageSize);
            return dictDatas;
        }
        [HttpPost("sysDictData/edit")]
        public async Task UpdateDictData(UpdateDictDataInput input)
        {
            var isExist = await _sysDictDataRep.AnyAsync(u => u.Id == input.Id, false);
            if (!isExist) throw Oops.Oh("字典值不存在");

            // 排除自己并且判断与其他是否相同
            isExist = await _sysDictDataRep.AnyAsync(u => (u.Value == input.Value || u.Code == input.Code) && u.DictTypeId == input.DictTypeId && u.Id != input.Id, false);
            if (isExist) throw Oops.Oh("字典值已存在,名称或编码重复");

            var dictData = input.Adapt<SysDictData>();
            await _sysDictDataRep.UpdateAsync(dictData, ignoreNullValues: true);
        }
    }
}
